﻿using TakeItIn.Data;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace TakeItIn
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class BasicPage : TakeItIn.Common.LayoutAwarePage
    {
        Note note;
        bool fReview;
        string reviewCategoryTitle;

        public BasicPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            if (pageState != null && pageState.ContainsKey("SelectedItem"))
            {
                navigationParameter = pageState["SelectedItem"];
            }

            var param = navigationParameter as Data.CurrentNote;

            this.fReview = param.fReview;
            this.reviewCategoryTitle = param.categoryTitle;

            if (param.id == null)
            {
                if (param.fReview)
                {
                    if (param.categoryTitle == "")
                        this.note = NoteDataSource.GetReviewCategorys()[0].Notes[0];
                    else
                        this.note = NoteDataSource.GetReviewCategory(param.categoryTitle).Notes[0];
                    this.DefaultViewModel["Notes"] = this.note.Category.Notes;
                    this.pageTitle.Text = this.note.Title;
                    this.noteTitle.Text = this.note.Title;
                    this.noteCategory.Text = this.note.Category.Title;
                    this.lastEditTime.Text = this.note.lastEditTime.ToString("MMM d, yyyy");
                    this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, this.note.Content);
                    UpdateNoteReviewData(ref this.note);
                }
                else
                {
                    note = null;
                    this.pageTitle.Text = "New Note";
                    this.noteTitle.Text = "Title";
                    this.lastEditTime.Visibility = Visibility.Collapsed;
                    this.noteTitle.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                    this.noteTitle.Tag = "empty";
                    this.noteCategory.Text = "Category";
                    this.noteCategory.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                    this.noteCategory.Tag = "empty";
                    this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.None, "Content");
                    this.noteContent.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                    this.noteContent.Tag = "empty";
                }
            }
            else
            {
                // TODO: Create an appropriate data model for your problem domain to replace the sample data
                this.note = NoteDataSource.GetNote(param.id);
                //this.DefaultViewModel["Categories"] = this.note.Category;
                this.DefaultViewModel["Notes"] = this.note.Category.Notes;
                this.pageTitle.Text = this.note.Title;
                this.noteTitle.Text = this.note.Title;
                this.noteCategory.Text = this.note.Category.Title;
                this.lastEditTime.Text = this.note.lastEditTime.Date.ToString("MMM d, yyyy");
                this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, this.note.Content);
                //this.flipView.SelectedItem = this.note;
            }
            this.noteTitle.IsReadOnly = this.fReview;
            this.noteCategory.IsReadOnly = this.fReview;
            this.noteContent.IsReadOnly = this.fReview;
            this.lastEditTime.IsReadOnly = true;
        }

        private void UpdateNoteReviewData(ref Note note)
        {
            note.lastReviewTime = DateTime.Today;
            if (note.reviewLevelCount == Note.maxReviewLevelCount)
            {
                note.reviewFequencyLevel++;
                note.reviewLevelCount = 1;
            }
            else
            {
                note.reviewLevelCount++;
            }
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

        protected void SaveNote()
        {
            if (this.fReview)
            {
                Note note = NoteDataSource.GetNote(this.note.Id);
                note.lastReviewTime = this.note.lastReviewTime;
                note.reviewFequencyLevel = this.note.reviewFequencyLevel;
                note.reviewLevelCount = this.note.reviewLevelCount;
            }
            else
            {
                string title = this.noteTitle.Tag as string == "empty" ? "" : this.noteTitle.Text;
                string category = this.noteCategory.Tag as string == "empty" ? "" : this.noteCategory.Text;

                string content;
                this.noteContent.Document.GetText(Windows.UI.Text.TextGetOptions.FormatRtf, out content);
                if (this.noteContent.Tag as string == "empty")
                    content = "";
                if (title != "" || content != "")
                {
                    if (this.note == null)
                    {
                        Note note = NoteDataSource.CreateNote(null, category, title, content, DateTime.Now);
                        NoteDataSource.CreateReviewCategory(this.noteCategory.Text).Notes.Insert(0, note);
                    }
                    else
                        NoteDataSource.ChangeNote(this.note.Id, category, title, content, DateTime.Now);
                }
            }
        }

        protected override void GoBack(object sender, RoutedEventArgs e)
        {
            SaveNote();
            base.GoBack(sender, e);
        }

        private void GetPrevNextNote(bool fNextNote, bool fReview)
        {
            NoteCategory category = fReview ? NoteDataSource.GetReviewCategory(this.note.Category.Title)
                                            : NoteDataSource.GetCategory(this.note.Category.Title);
            int current = category.Notes.IndexOf(this.note);
            if (fNextNote)
            {
                if (current < category.Notes.Count - 1)
                {
                    this.note = category.Notes[current + 1];
                }
                else if (!fReview || this.reviewCategoryTitle == "")
                {
                    ObservableCollection<NoteCategory> allCategories = fReview ? NoteDataSource.GetReviewCategorys()
                                                                               : NoteDataSource.GetCategorys();
                    int currentCategory = allCategories.IndexOf(category);
                    if (currentCategory < allCategories.Count - 1)
                        this.note = allCategories[currentCategory + 1].Notes[0];
                }
            }
            else
            {
                if (current > 0)
                {
                    this.note = category.Notes[current - 1];
                }
                else if (!fReview || this.reviewCategoryTitle == "")
                {
                    ObservableCollection<NoteCategory> allCategories = fReview ? NoteDataSource.GetReviewCategorys()
                                                                               : NoteDataSource.GetCategorys();
                    int currentCategory = allCategories.IndexOf(category);
                    if (currentCategory > 0)
                    {
                        ObservableCollection<Note> notes = allCategories[currentCategory - 1].Notes;
                        this.note = notes[notes.Count - 1];
                    }
                }
            }
        }

        private void PrevNextNote(object sender, RoutedEventArgs e)
        {
            if (this.note == null)
                return;

            bool nextNote = true;
            if (((Windows.UI.Xaml.FrameworkElement)(sender)).Name == "PrevNote")
            {
                nextNote = false;
            }

            SaveNote();

            GetPrevNextNote(nextNote, this.fReview);

            this.pageTitle.Text = this.note.Title;
            this.noteTitle.Text = this.note.Title;
            this.noteCategory.Text = this.note.Category.Title;
            this.noteContent.IsReadOnly = false;
            this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, this.note.Content);
            this.noteContent.IsReadOnly = this.fReview;
            if (this.fReview)
                UpdateNoteReviewData(ref this.note);
        }

        private void TextControlGotFocus(object sender, RoutedEventArgs e)
        {
            switch (((Windows.UI.Xaml.FrameworkElement)(sender)).Name)
            {
                case "noteTitle":
                    if (this.noteTitle.Tag as string == "empty")
                    {
                        this.noteTitle.Text = "";
                        this.noteTitle.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
                        this.noteTitle.Tag = "";
                    }
                    break;
                case "noteCategory":
                    if (this.noteCategory.Tag as string == "empty")
                    {
                        this.noteCategory.Text = "";
                        this.noteCategory.Foreground = new SolidColorBrush(Windows.UI.Colors.Black);
                        this.noteCategory.Tag = "";
                    }
                    break;
                case "noteContent":
                    if (this.noteContent.Tag as string == "empty")
                    {
                        this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.None, "");
                        this.noteContent.Foreground = new SolidColorBrush(Windows.UI.Colors.Black);
                        this.noteContent.Tag = "";
                    }
                    break;
            }
        }

        private void TextControlLostFocus(object sender, RoutedEventArgs e)
        {
            switch (((Windows.UI.Xaml.FrameworkElement)(sender)).Name)
            {
                case "noteTitle":
                    if (this.noteTitle.Text == "")
                    {
                        this.noteTitle.Text = "Title";
                        this.noteTitle.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                        this.noteTitle.Tag = "empty";
                    }
                    break;
                case "noteCategory":
                    if (this.noteCategory.Text == "")
                    {
                        this.noteCategory.Text = "Category";
                        this.noteCategory.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                        this.noteCategory.Tag = "empty";
                    }
                    break;
                case "noteContent":
                    string content;
                    this.noteContent.Document.GetText(Windows.UI.Text.TextGetOptions.None, out content);
                    if (content == "\r")
                    {
                        this.noteContent.Document.SetText(Windows.UI.Text.TextSetOptions.None, "Content");
                        this.noteContent.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
                        this.noteContent.Tag = "empty";
                    }
                    break;
            }
        }
    }
}
